package com.clx.admin.service.Impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;

import com.clx.admin.mapper.UserMapper;
import com.clx.admin.service.UserService;
import com.clx.common.domain.dto.UpdateUserDto;
import com.clx.common.domain.entity.DiskUser;
import com.clx.common.domain.vo.AjaxResult;
import com.clx.common.utils.PasswordUtil;
import com.clx.common.utils.StringUtils;
import io.minio.BucketExistsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import com.clx.common.utils.DateUtils;

import java.io.InputStream;
import java.util.List;
import java.util.UUID;

/**
 * 用户表(User)表服务实现类
 *
 * @author clx
 * @since 2025-01-08 14:33:09
 */
@Service("userService")
@RequiredArgsConstructor
public class UserServiceImpl implements UserService {

    private final UserMapper userMapper;

    private final MinioClient minioClient;

    @Value("${minio.endpoint}")
    private String minioUrl;

    /**
     * 查询数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public DiskUser selectUserById(Long id) {
        return userMapper.selectUserById(id);
    }

    /**
     * 查询列表
     *
     * @param user 筛选条件
     * @return 查询结果
     */
    @Override
    public List<DiskUser> selectUserList(DiskUser user) {
        DiskUser entity = user;
        return (userMapper.selectUserList(entity));
    }

    /**
     * 新增数据
     *
     * @param user 实例对象
     * @return 受影响的行数，新增成功通常返回1，失败返回0等
     */
    @Override
    public int insertUser(DiskUser user) {
        DiskUser entity = user;
        entity.setCreateTime(DateUtils.getNowDate());
        return (userMapper.insertUser(entity));
    }

    /**
     * 修改数据
     *
     * @param user 实例对象
     * @return 受影响的行数，一般成功修改返回1
     */
    @Override
    public int updateUser(DiskUser user) {
        DiskUser entity = user;
        entity.setUpdateTime(DateUtils.getNowDate());
        return (userMapper.updateUser(entity));
    }

    /**
     * 批量删除数据
     *
     * @param ids 需要删除的主键数组
     * @return 受影响的行数，即成功删除的记录数
     */
    @Override
    public int deleteUserByIds(Long[] ids) {
        return (userMapper.deleteUserByIds(ids));
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功（以受影响行数判断，成功返回1等）
     */
    @Override
    public int deleteUserById(Long id) {
        return (userMapper.deleteUserById(id));
    }

    /**
     * 查询单个user对象
     * @param user
     * @return
     */
    @Override
    public DiskUser selectByUser(DiskUser user) {
        return userMapper.selectByUser(user);
    }



    /**
     * 根据用户id返回用户信息
     */
    @Override
    public AjaxResult all(Long userId) {
        DiskUser user = userMapper.all(userId);
        return AjaxResult.success(null,user);
    }



    /**
     * 上传用户头像
     * @param file
     * @return
     */
    public String uploadAvatar(MultipartFile file)  {
        String bucketName= null;
        String fileName = null;
        try {
            bucketName = "user-avatar";
            BucketExistsArgs bucket = BucketExistsArgs.builder().bucket(bucketName).build();
            // 检查存储桶是否存在，不存在则创建
            if (!minioClient.bucketExists(bucket)) {
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
            }

            // 生成唯一的文件名
            fileName = UUID.randomUUID().toString() + "-" + file.getOriginalFilename();

            try (InputStream inputStream = file.getInputStream()) {
                // 上传文件到 MinIO
                PutObjectArgs putObjectArgs = PutObjectArgs.builder()
                        .bucket(bucketName)
                        .object(fileName)
                        .stream(inputStream, file.getSize(), -1)
                        .contentType(file.getContentType())
                        .build();
                minioClient.putObject(putObjectArgs);
                String presignedObjectUrl=minioUrl+"/" + bucketName + "/" + fileName;
                //存储到数据库
                DiskUser user=new DiskUser();
                user.setId(StpUtil.getLoginIdAsLong());
                user.setAvatar(presignedObjectUrl);
                userMapper.updateUser(user);
                // 返回文件的访问路径
                return presignedObjectUrl;
            } catch (Exception e) {
                throw new RuntimeException("文件上传失败", e);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 更新个人资料
     * @param updateUserDto
     * @return
     */
    @Override
    public AjaxResult updateUserDto(UpdateUserDto updateUserDto) {
        long userId = StpUtil.getLoginIdAsLong();
        if (!StringUtils.isEmpty(updateUserDto.getOldPassword())){
            //旧密码不是空  修改密码
            DiskUser user=new DiskUser();
            user.setId(userId);
            DiskUser tempUser = userMapper.selectUserById(userId);
            boolean matches = PasswordUtil.matches(updateUserDto.getOldPassword(), tempUser.getPassword());
            if (!matches){
                return AjaxResult.error( "旧密码不正确", null);
            }
            //更新新密码到数据库
            String newPassword = PasswordUtil.encodePassword(updateUserDto.getNewPassword());
            user.setPassword(newPassword);
            int i = userMapper.updateUser(user);
            if (i<0){
                return AjaxResult.error("更新个人资料失败");
            }
            return AjaxResult.success("更新密码成功");
        }
        DiskUser user=new DiskUser();
        user.setUsername(updateUserDto.getUsername());
        user.setEmail(updateUserDto.getEmail());
        user.setId(userId);
        int i = userMapper.updateUser(user);
        if (i<0){
            return AjaxResult.error("更新个人资料失败");
        }

        return AjaxResult.success("更新个人资料成功");
    }
}
